#ifndef FLAT_KIT_OUTLINE_INCLUDED #define FLAT_KIT_OUTLINE_INCLUDED TEXTURE2D_X (_BlitTexture); SAMPLER (sampler_BlitTexture); float Linear01Depth(float z) { const float isOrtho = unity_OrthoParams.w; const float isPers = 1.0 - unity_OrthoParams.w; z *= _ZBufferParams.x; return (1.0 - isOrtho * z) / (isPers * z + _ZBufferParams.y); } float SampleDepth(float2 uv) { const float d = SampleSceneDepth(uv); return Linear01Depth(d); } float4 SampleCameraColor(float2 uv) { return SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_BlitTexture, UnityStereoTransformScreenSpaceTex(uv)); } void Outline_float(float2 UV, out float4 Out) { float4 original = SampleCameraColor(UV); const float offset_positive = +ceil(_Thickness * 0.5f); const float offset_negative = -floor(_Thickness * 0.5f); #if RESOLUTION_INVARIANT_THICKNESS const float screen_ratio = _ScreenSize.x / _ScreenSize.y; const float2 texel_size = 1.0 / 800.0 * float2(1.0, screen_ratio); #else const float2 texel_size = _ScreenSize.zw; #endif float left = texel_size.x * offset_negative; float right = texel_size.x * offset_positive; float top = texel_size.y * offset_negative; float bottom = texel_size.y * offset_positive; const float2 uv0 = UV + float2(left, top); const float2 uv1 = UV + float2(right, bottom); const float2 uv2 = UV + float2(right, top); const float2 uv3 = UV + float2(left, bottom); #ifdef OUTLINE_USE_DEPTH const float d0 = SampleDepth(uv0); const float d1 = SampleDepth(uv1); const float d2 = SampleDepth(uv2); const float d3 = SampleDepth(uv3); const float depth_threshold_scale = 300.0f; float d = length(float2(d1 - d0, d3 - d2)) * depth_threshold_scale; d = smoothstep(_DepthThresholdMin, _DepthThresholdMax, d); #else float d = 0.0f; #endif // OUTLINE_USE_DEPTH #ifdef OUTLINE_USE_NORMALS const float3 n0 = SampleSceneNormals(uv0); const float3 n1 = SampleSceneNormals(uv1); const float3 n2 = SampleSceneNormals(uv2); const float3 n3 = SampleSceneNormals(uv3); const float3 nd1 = n1 - n0; const float3 nd2 = n3 - n2; float n = sqrt(dot(nd1, nd1) + dot(nd2, nd2)); n = smoothstep(_NormalThresholdMin, _NormalThresholdMax, n); #else float n = 0.0f; #endif // OUTLINE_USE_NORMALS #ifdef OUTLINE_USE_COLOR const float3 c0 = SampleCameraColor(uv0).rgb; const float3 c1 = SampleCameraColor(uv1).rgb; const float3 c2 = SampleCameraColor(uv2).rgb; const float3 c3 = SampleCameraColor(uv3).rgb; const float3 cd1 = c1 - c0; const float3 cd2 = c3 - c2; float c = sqrt(dot(cd1, cd1) + dot(cd2, cd2)); c = smoothstep(_ColorThresholdMin, _ColorThresholdMax, c); #else float c = 0; #endif // OUTLINE_USE_COLOR const float g = max(d, max(n, c)); #ifdef OUTLINE_FADE_OUT const float linear_depth = LinearEyeDepth(SampleSceneDepth(UV), _ZBufferParams); const float fade = smoothstep(_FadeRangeEnd, _FadeRangeStart, linear_depth); _EdgeColor.a *= fade; #endif // OUTLINE_FADE_OUT #ifdef OUTLINE_ONLY original.rgb = lerp(1.0 - _EdgeColor.rgb, _EdgeColor.rgb, g * _EdgeColor.a); #endif // OUTLINE_ONLY float4 output; output.rgb = lerp(original.rgb, _EdgeColor.rgb, g * _EdgeColor.a); output.a = original.a; Out = output; } #endif // FLAT_KIT_OUTLINE_INCLUDED